package com.xuerhua.yxt.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.xuerhua.yxt.common.Const;
import com.xuerhua.yxt.common.MenuConst;
import com.xuerhua.yxt.common.RspResult;
import com.xuerhua.yxt.common.enums.DictDataCode;
import com.xuerhua.yxt.common.enums.RelationType;
import com.xuerhua.yxt.common.enums.Status;
import com.xuerhua.yxt.dao.AttachmentListMapper;
import com.xuerhua.yxt.dao.KccsCourseInfoMapper;
import com.xuerhua.yxt.dao.KccsSignTimeMapper;
import com.xuerhua.yxt.dao.KccsStudentSignMapper;
import com.xuerhua.yxt.dao.SchoolWechatTemplateMapper;
import com.xuerhua.yxt.dao.TeacherInfoMapper;
import com.xuerhua.yxt.exception.ExpirationException;
import com.xuerhua.yxt.model.AttachmentList;
import com.xuerhua.yxt.model.Grid;
import com.xuerhua.yxt.model.KccsCourseInfo;
import com.xuerhua.yxt.model.KccsSignTime;
import com.xuerhua.yxt.model.KccsStudentSign;
import com.xuerhua.yxt.model.SchoolInfo;
import com.xuerhua.yxt.model.TeacherInfo;
import com.xuerhua.yxt.page.Page;
import com.xuerhua.yxt.reqVo.AttachRelationReqVO;
import com.xuerhua.yxt.reqVo.BaseQueryVO;
import com.xuerhua.yxt.reqVo.KccsCourseQueryVO;
import com.xuerhua.yxt.reqVo.KccsCourseReqVO;
import com.xuerhua.yxt.reqVo.KccsStudentSignReqVO;
import com.xuerhua.yxt.service.IKccsCourseInfoService;
import com.xuerhua.yxt.service.ISchoolInfoService;
import com.xuerhua.yxt.utils.BeanUtils;
import com.xuerhua.yxt.view.KccsCourseStudentSignView;
import com.xuerhua.yxt.view.KccsCourseStudentSignedView;
import com.xuerhua.yxt.view.KccsCourseView;
import com.xuerhua.yxt.view.KccsStudentTotalView;
import com.xuerhua.yxt.wechat.utils.TemplateUtil;

@Service("kccsCourseInfoService")
public class KccsCourseInfoServiceImpl implements IKccsCourseInfoService {

	@Autowired
	private KccsCourseInfoMapper kccsCourseInfoMapper;
	@Autowired
	private AttachmentListMapper attachmentListMapper;
	@Autowired
	private KccsStudentSignMapper kccsStudentSignMapper;
	@Autowired
	private TeacherInfoMapper teacherInfoMapper;
	@Autowired
	private KccsSignTimeMapper kccsSignTimeMapper;
	@Autowired
	private ISchoolInfoService schoolInfoService;
	@Autowired
	private SchoolWechatTemplateMapper schoolWechatTemplateMapper;
	
	@Override
	public int insertSelective(KccsCourseInfo record) {
		return kccsCourseInfoMapper.insertSelective(record);
	}

	@Override
	public KccsCourseInfo selectByPrimaryKey(Integer id) {
		return kccsCourseInfoMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<KccsCourseInfo> selectList(KccsCourseQueryVO vo) {
		return kccsCourseInfoMapper.selectList(vo);
	}

	@Override
	public Grid selectListByPage(KccsCourseQueryVO vo) {
		Page<KccsCourseInfo> page = new Page<>();
		page.setPageNo(vo.getPage());
		page.setPageSize(vo.getRows());
		page.setParams(vo);
		List<KccsCourseInfo> list = kccsCourseInfoMapper.selectListByPage(page);
		Grid grid = new Grid();
		grid.setRows(list);
		grid.setTotal(page.getTotalRecord());
		return grid;
	}

	@Override
	public int updateByPrimaryKeySelective(KccsCourseInfo record) {
		return kccsCourseInfoMapper.updateByPrimaryKeySelective(record);
	}
	
	@Override
	public KccsCourseView selectSignCourseDetail(BaseQueryVO vo) {
		KccsCourseView view = kccsCourseInfoMapper.selectSignCourseDetail(vo);
		if(StringUtils.isNotBlank(view.getMainImg())) {
			Map<String, Object> map = new HashMap<>();
			map.put("type", RelationType.KCCS_COURSE.getCode());
			map.put("objId", vo.getId());
			map.put("schoolId", vo.getSchoolId());
			List<AttachmentList> attachmentList = attachmentListMapper.queryAttachmentListByRelationId(map);
			view.setAttachList(attachmentList);
		}
		return view;
	}

	@Override
	public void addAndUpdate(KccsCourseReqVO vo) {
		if(vo.getId() == null) {
			kccsCourseInfoMapper.insertSelective(vo);
			if(StringUtils.isNotBlank(vo.getAttachIds())) {
				AttachRelationReqVO attachReqVO = new AttachRelationReqVO();
				String[] array = vo.getAttachIds().split(",");
				attachReqVO.setRelationId(Long.valueOf(vo.getId()));
				attachReqVO.setAttachIds(array);
				attachReqVO.setSchoolId(vo.getSchoolId());
				attachmentListMapper.updateRelationIdByIds(attachReqVO);
			}
		}else {
			kccsCourseInfoMapper.updateByPrimaryKeySelective(vo);
			AttachRelationReqVO attachReqVO = new AttachRelationReqVO();
			attachReqVO.setRelationId(Long.valueOf(vo.getId()));
			attachReqVO.setSchoolId(vo.getSchoolId());
			if(StringUtils.isNotBlank(vo.getAttachIds())) {
				String[] array = vo.getAttachIds().split(",");
				attachReqVO.setAttachIds(array);
			}else {
				String[] array = {"0"};
				attachReqVO.setAttachIds(array);
			}
			attachmentListMapper.updateInvaildForRevByIds(attachReqVO);
			if(StringUtils.isNotBlank(vo.getAttachIds())) {
				attachmentListMapper.updateRelationIdByIds(attachReqVO);
			}
		}
	}

	@Override
	public List<KccsCourseStudentSignView> selectSignedListForClass(KccsCourseQueryVO vo) {
		return kccsStudentSignMapper.selectSignedListForClass(vo);
	}

	@Override
	public List<KccsCourseStudentSignView> selectNoSignListForClass(KccsCourseQueryVO vo) {
		return kccsStudentSignMapper.selectNoSignListForClass(vo);
	}

	@Override
	public KccsCourseStudentSignView selectSignedCourseForStudent(KccsCourseQueryVO vo) {
		return kccsStudentSignMapper.selectSignedCourseForStudent(vo);
	}

	@Override
	public List<KccsCourseStudentSignView> selectSignListForParent(KccsCourseQueryVO vo) {
		return kccsStudentSignMapper.selectSignListForParent(vo);
	}
	
	@Override
	public RspResult insertSign(KccsStudentSignReqVO reqVO) {
		for(KccsStudentSign record : reqVO.getList()) {
			KccsCourseQueryVO vo = new KccsCourseQueryVO();
			vo.setTermId(reqVO.getTermId());
			vo.setCourseId(record.getCourseId());
			vo.setSchoolId(reqVO.getSchoolId());
			if(isCourseSignLimit(vo)) {
				return new RspResult(Status.FAIL.getCode(), 
						record.getCourseName() + "课程人数已满，请选择其它课程！");
			}
		}
		int result = kccsStudentSignMapper.insertSign(reqVO);
		if(result > 0) {
			return new RspResult(Status.SUCCESS);
		}
		return new RspResult(Status.FAIL);
	}

	@Override
	public RspResult updateChangeSign(KccsStudentSignReqVO reqVO) {
		kccsStudentSignMapper.updateInvalidStudentSign(reqVO);
		for(KccsStudentSign record : reqVO.getList()) {
			KccsCourseQueryVO vo = new KccsCourseQueryVO();
			vo.setTermId(reqVO.getTermId());
			vo.setCourseId(record.getCourseId());
			vo.setSchoolId(reqVO.getSchoolId());
			if(isCourseSignLimit(vo)) {
				throw new ExpirationException(record.getCourseName() + "课程人数已满，请选择其它课程！");
			}
		}
		int result = kccsStudentSignMapper.insertSign(reqVO);
		if(result > 0) {
			return new RspResult(Status.SUCCESS);
		}
		return new RspResult(Status.FAIL);
	}

	@Override
	public boolean isFullForCourseId(BaseQueryVO vo) {
		KccsCourseInfo courseInfo = kccsCourseInfoMapper.selectByPrimaryKey(vo.getId());
		if(courseInfo.getLimitNum() != null) {
			int count = kccsStudentSignMapper.seletCountByCourseId(vo);
			if(count >= courseInfo.getLimitNum().intValue()) {
				return true;
			}
		}
		return false;
	}

	@Override
	public List<KccsCourseStudentSignView> selectSignListForTeachingByCourseId(KccsCourseQueryVO vo) {
		return kccsStudentSignMapper.selectSignListForTeachingByCourseId(vo);
	}

	@Override
	public List<KccsCourseView> selectSignCourseList(KccsCourseQueryVO vo) {
		return kccsCourseInfoMapper.selectSignCourseList(vo);
	}

	@Override
	public boolean isCourseSignLimit(KccsCourseQueryVO vo) {
		int result = kccsCourseInfoMapper.selectCourseSignLimit(vo);
		return result > 0 ? false : true;
	}
	
	@Override
	public KccsCourseView selectViewById(KccsCourseQueryVO vo) {
		KccsCourseInfo courseInfo = kccsCourseInfoMapper.selectViewById(vo);
		KccsCourseView view = BeanUtils.copyAs(courseInfo, KccsCourseView.class);
		if(StringUtils.isNotBlank(view.getMainImg())) {
			Map<String, Object> map = new HashMap<>();
			map.put("type", RelationType.KCCS_COURSE.getCode());
			map.put("objId", vo.getCourseId());
			map.put("schoolId", vo.getSchoolId());
			List<AttachmentList> attachmentList = attachmentListMapper.queryAttachmentListByRelationId(map);
			view.setAttachList(attachmentList);
		}
		return view;
	}

	@Override
	public List<KccsCourseInfo> selectListForTeaching(Integer teacherId, Integer schoolId) {
		return kccsCourseInfoMapper.selectListForTeaching(teacherId,schoolId);
	}
	
	@Override
	public List<KccsCourseInfo> selectMyCreateList(Integer teacherId) {
		return kccsCourseInfoMapper.selectMyCreateList(teacherId);
	}

	@Override
	public Grid selectSignListByPage(KccsCourseQueryVO vo) {
		Page<KccsCourseStudentSignedView> page = new Page<>();
		page.setPageNo(vo.getPage());
		page.setPageSize(vo.getRows());
		page.setParams(vo);
		List<KccsCourseStudentSignedView> list = kccsStudentSignMapper.selectSignListByPage(page);
		Grid grid = new Grid();
		grid.setRows(list);
		grid.setTotal(page.getTotalRecord());
		return grid;
	}

	@Override
	public Grid selectKccsStudentTotal(KccsCourseQueryVO vo) {
		Page<KccsStudentTotalView> page = new Page<>();
		page.setPageNo(vo.getPage());
		page.setPageSize(vo.getRows());
		page.setParams(vo);
		List<KccsStudentTotalView> list = kccsStudentSignMapper.selectKccsStudentTotal(page);
		Grid grid = new Grid();
		grid.setRows(list);
		grid.setTotal(page.getTotalRecord());
		return grid;
	}

	@Override
	public int delKccsCourse(List<String> list) {
		return kccsCourseInfoMapper.delKccsCourse(list);
	}

	@Override
	public int updateBatchCourseStatus(List<String> list, Integer isAgree, Integer updaterId, String updater, Integer schoolId) {
		return kccsCourseInfoMapper.updateBatchCourseStatus(list, isAgree, updaterId, updater, schoolId);
	}

	@Override
	public int updateBatchCourseInfo(List<KccsCourseInfo> list) {
		for(KccsCourseInfo courseInfo : list) {
			kccsCourseInfoMapper.insertReplace(courseInfo);
		}
		return 1;
	}

	@Override
	public List<KccsCourseInfo> selectPendingList(Page<KccsCourseInfo> page) {
		return kccsCourseInfoMapper.selectPendingList(page);
	}

	@Override
	public List<KccsCourseInfo> selectApprovedList(Page<KccsCourseInfo> page) {
		return kccsCourseInfoMapper.selectApprovedList(page);
	}

	@Override
	public RspResult updateApprovalCourse(KccsCourseReqVO vo) {
		KccsCourseQueryVO kcqvo = new KccsCourseQueryVO();
		kcqvo.setSchoolId(vo.getSchoolId());
		//KccsCourseReqVO里继承的父类Long id了，这里需要Integer，先借用CourseId,怕Long和Integer互转出BUG
		kcqvo.setCourseId(vo.getId());
		KccsCourseInfo courseInfo = kccsCourseInfoMapper.selectViewById(kcqvo);
		if(courseInfo.getIsAgree() != 0) {
			return new RspResult(Status.EXPIRED_DATA);
		}
		vo.setUpdateTime(new Date());
		addAndUpdate(vo);
		courseInfo.setIsAgree(vo.getIsAgree());
		ThreadExecute(courseInfo);
		return new RspResult(Status.SUCCESS);
	}
	
	void ThreadExecute(KccsCourseInfo apply) {
		TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
	        @Override
	        public void afterCommit() {
	        	SchoolInfo school = schoolInfoService.queryInitWechatBySchoolId(apply.getSchoolId());
	        	String templateId = schoolWechatTemplateMapper.selectTemplateKey(
						apply.getSchoolId(), DictDataCode.WORK_APPROVAL_RESULT.getCode());
	        	String reqUrl = school.getDomainUrl() + Const.TEACHER_ROLE + 
	        			MenuConst.KCCS_COURSE + "/detail/" + apply.getId();
	        	TeacherInfo teacher = teacherInfoMapper.selectByPrimaryKey(apply.getCreaterId());
	        	TemplateUtil.approvalResultSend(school,teacher.getOpenid(), "您好！您创建的课程已被审批", "课程超市", 
						apply.getIsAgree() == 1 ? "同意开课" : "不同意开课", new Date(), templateId, reqUrl);
	        }
	    });
	}

	@Override
	public int updateKccsEndDate(KccsSignTime record) {
		return kccsSignTimeMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public KccsSignTime selectKccsEndDate(Integer schoolId) {
		return kccsSignTimeMapper.selectKccsEndDate(schoolId);
	}

	@Override
	public int addSpecialSign(KccsStudentSign record) {
		KccsStudentSignReqVO reqVO = new KccsStudentSignReqVO();
		reqVO.setStudentId(record.getStudentId());
		reqVO.setTermId(record.getTermId());
		reqVO.setSchoolId(record.getSchoolId());
		kccsStudentSignMapper.updateInvalidStudentSign(reqVO);
		return kccsStudentSignMapper.insertSelective(record);
	}

	@Override
	public int batchAddStudentSign(List<KccsStudentSign> list) {
		return kccsStudentSignMapper.batchAddStudentSign(list);
	}

	@Override
	public int delStudentSignByIds(List<String> list) {
		return kccsStudentSignMapper.delByIds(list);
	}
	
}
